<script>
import closeIcon from "./assets/close.svg"
import { cloneDeep } from "@/utils"
import myRadio from "@/components/myRadio/index.vue"

export default {
  name: "index",
  props: {
    data: {
      type: Array,
      default: () => [],
    },
    valueKey: {
      type: String,
      default: "value",
    },
    labelKey: {
      type: String,
      default: "label",
    },
    childrenKey: {
      type: String,
      default: "children",
    },
    value: {
      type: Array,
      default: () => [],
    },
    // 父节点是否只能单选
    singleSelectionAtParentLevel: {
      type: Boolean,
      default: false,
    },
    title: {
      type: String,
      default: "请选择",
    },
  },
  components: { myRadio },
  data() {
    return {
      closeIcon,
      dataList: [],
      currentHoverParentNode: null,
    }
  },
  methods: {
    open() {
      // 初始化变量
			let dataList
			if (this.dataList.length === 0) {
				dataList = cloneDeep(this.data)
				for (let datum of dataList) {
					datum.selected = false
					if (datum[this.childrenKey] && datum[this.childrenKey].length > 0) {
						for (let child of datum[this.childrenKey]) {
							child.selected = false
						}
					}
				}
				// 已经初始化过了
			} else {
				dataList = this.dataList
			}
      // 数据回显
      if (this.value.length > 0) {
        let currentHoverParentNode
        this.value.forEach((item) => {
          const parent = dataList.find((parent) => parent[this.valueKey] === item[this.valueKey])
          if (parent) {
            parent.selected = true
            currentHoverParentNode = parent
            if (parent[this.childrenKey] && parent[this.childrenKey].length > 0) {
              item[this.childrenKey].forEach((child) => {
                const childNode = parent[this.childrenKey].find((childNode) => childNode[this.valueKey] === child[this.valueKey])
                if (childNode) {
                  childNode.selected = true
                }
              })
            }
          }
        })
        this.currentHoverParentNode = currentHoverParentNode
        this.dataList = dataList
      } else {
        // 默认选中第一个父节点
        dataList[0].selected = true
        this.currentHoverParentNode = dataList[0]
        this.dataList = dataList
      }
      this.$refs.popup.open()
    },
    confirm() {
      let result = []
      this.dataList.forEach((item) => {
        const localItem = {
          ...item,
          [this.childrenKey]: [],
        }
        if (localItem.selected && item[this.childrenKey] && item[this.childrenKey].length > 0) {
          result.push(localItem)
          item[this.childrenKey].forEach((child) => {
            if (child.selected) {
              localItem[this.childrenKey].push(child)
            }
          })
        }
      })
      this.$emit("input", result)
      this.$emit("change", result)
      this.$refs.popup.close()
    },
    // 父节点单选模式清空其余的父节点里面的选中项
    clearOtherParentSelected(item) {
      if (this.singleSelectionAtParentLevel) {
        for (let dataListElement of this.dataList) {
          if (dataListElement !== item && dataListElement.selected) {
            dataListElement.selected = false
            dataListElement[this.childrenKey].forEach((child) => {
              child.selected = false
            })
          }
        }
      }
    },
    // 点击了子节点
    selectChildItem(item, parent) {
      item.selected = !item.selected
      this.currentHoverParentNode = parent
    },
    // 选择/取消选择全部子节点
    selectAllChildItem(parent) {
      if (parent.hasSelectedAll) {
        parent[this.childrenKey].forEach((child) => {
          child.selected = false
        })
        parent.hasSelectedAll = false
      } else {
        parent[this.childrenKey].forEach((child) => {
          child.selected = true
        })
        parent.hasSelectedAll = true
      }
    },
    // 点击了父节点
    selectParentItem(item) {
      this.clearOtherParentSelected(item)
      item.selected = true
      this.currentHoverParentNode = item
    },
    // 重置选择
    reset() {
      this.dataList = cloneDeep(this.data)
      this.currentHoverParentNode = this.dataList[0]
    },
  },
  emits: ["change", "input"],
}
</script>

<template>
  <uni-popup ref="popup" type="bottom">
    <view class="popup-content">
      <view class="header">
        <view class="placeholder"></view>
        <view class="title">{{ title }}</view>
        <image class="close-btn" :src="closeIcon" @click="$refs.popup.close()"></image>
      </view>
      <view class="list">
        <view class="parent-side">
          <view
            class="item"
            v-for="item in dataList"
            :key="item[valueKey]"
            :class="{
              selected: item.selected,
              hover: currentHoverParentNode[valueKey] === item[valueKey],
            }"
            @click="selectParentItem(item)"
            >{{ item[labelKey] }}</view
          >
        </view>
        <view class="child-side">
          <view
            class="item"
            @click="selectAllChildItem(currentHoverParentNode)"
            :class="{ selected: currentHoverParentNode.hasSelectedAll }"
          >
            <view class="label">全选</view>
            <my-radio :check="currentHoverParentNode.hasSelectedAll"></my-radio>
          </view>
          <view
            class="item"
            v-for="child in currentHoverParentNode[childrenKey]"
            :key="child[valueKey]"
            :class="{ selected: child.selected }"
            @click="selectChildItem(child, currentHoverParentNode)"
          >
            <view class="label">{{ child[labelKey] }}</view>
            <my-radio :check="child.selected"></my-radio>
          </view>
        </view>
      </view>
      <view class="footer">
        <view class="reset-btn btn" @click="reset">重置</view>
        <view class="confirm-btn btn" @click="confirm">确定</view>
      </view>
    </view>
  </uni-popup>
</template>

<style scoped lang="scss">
.popup-content {
  background: white;
  border-radius: 40rpx 40rpx 0 0;
  > .header {
    padding: 30rpx;
    display: flex;
    align-items: center;
    justify-content: space-between;
    > .title {
      font-size: 34rpx;
    }
    > .close-btn,
    > .placeholder {
      width: 40rpx;
      height: 40rpx;
    }
  }
  > .list {
    display: flex;
    height: 60vh;
    > .parent-side {
      width: 30%;
      background: var(--gray-background-color);
      overflow-y: auto;
      > .item {
        padding: 30rpx 30rpx;
        font-size: 30rpx;
        // 文本溢出自动加省略号
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        &.selected {
          color: var(--text-color-theme);
        }
        &.hover {
          background: white;
        }
      }
    }
    > .child-side {
      width: 70%;
      overflow-y: auto;
      > .item {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 30rpx 30rpx;
        font-size: 30rpx;
        > .label {
          flex: 1;
          // 文本溢出自动加省略号
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
        > my-radio {
          width: 40rpx;
          height: 40rpx;
        }
        &.selected {
          color: var(--text-color-theme);
        }
      }
    }
  }
  > .footer {
    display: flex;
    justify-content: space-between;
    padding: 30rpx;
    > .btn {
      width: 45%;
      height: 80rpx;
      line-height: 80rpx;
      text-align: center;
      border-radius: 40rpx;
      font-size: 30rpx;
      &.reset-btn {
        border: 2rpx solid var(--theme-color);
        color: var(--text-color-theme);
      }
      &.confirm-btn {
        background: var(--theme-color);
        color: white;
      }
    }
  }
}
</style>
